import 'package:flutter/material.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:waterfall_flow/waterfall_flow.dart';
import 'package:xws/helpers/safe_state.dart';
import 'package:xws/utils/log_util.dart';
import 'empty_view.dart';
import 'loading_view.dart';
import 'refresh_view.dart';

/// 视图样式
/// `list` 列表
/// `grid` 网格
enum ViewType { list, grid, waterfall }

/// 列表刷新/加载视图
class RefreshLoadView<T> extends StatefulWidget {
  const RefreshLoadView({
    Key? key,
    this.pageSize = 10,
    required this.itemBuilder,
    required this.onRefresh,
    this.separatorBuilder,
    this.onLoad,
    this.scrollController,
    this.padding = EdgeInsets.zero,
    this.splitWidget = const SizedBox(height: 5),
    this.onInit,
    this.onListChange,
    this.viewController,
    this.scrollDirection = Axis.vertical,
    this.type = ViewType.list,
    this.gridDelegate,
    this.useClickToRefresh = true,
    this.cacheExtent,
    this.waterfallDelegate,
  }) : super(key: key);

  /// 每页数据条数，默认每页10条
  final int pageSize;

  /// 滚动控制器
  final ScrollController? scrollController;

  /// 刷新视图控制器
  final RefreshViewController<T>? viewController;

  /// 项目构建器
  /// * `index` 索引
  /// * `modle` 数据模型，使用时需要自行进行强转
  /// * `final User user = modle as User;`
  final Widget Function(int index, T modle) itemBuilder;

  /// 分隔符构建器,会完全覆盖分隔符控件
  final Widget Function(BuildContext context, int index)? separatorBuilder;

  /// 刷新事件
  /// * `size` 每页数据条数
  final Future<List<T>> Function(int size, bool refreshByController) onRefresh;

  /// 初始化事件
  /// 刷新完成后这个方法会将首次获得的数据返回
  final Future<void> Function(List<T> list)? onInit;

  /// 列表数据变化回调
  final Future<void> Function(List<T> list)? onListChange;

  /// 加载事件
  /// * `page` 当前分页索引
  /// * `size` 每页数据条数
  final Future<List<T>> Function(int page, int size)? onLoad;

  /// 边距
  final EdgeInsetsGeometry padding;

  /// 预加载范围
  final double? cacheExtent;

  /// 分隔符控件
  final Widget splitWidget;

  /// 滚动方向
  final Axis scrollDirection;

  /// 视图样式
  final ViewType type;

  /// 网格样式
  final SliverGridDelegate? gridDelegate;

  /// 瀑布流样式
  final SliverWaterfallFlowDelegate? waterfallDelegate;

  /// 使用点击刷新(true)或下拉刷新(false)
  final bool useClickToRefresh;

  @override
  _RefreshLoadViewState<T> createState() => _RefreshLoadViewState<T>();
}

class _RefreshLoadViewState<T> extends State<RefreshLoadView<T>> with SafeState<RefreshLoadView<T>> {
  /// 对象数据列表
  final List<T> _dataList = <T>[];

  /// 请求分页
  int _page = 1;

  /// 通过控制器刷新
  bool _rByC = false;

  /// 刷新控制器
  late RefreshController _refreshController;

  /// 是否可以继续加载的文字提示
  String _canLoadText = '';

  @override
  void initState() {
    super.initState();
    _refreshController = RefreshController(initialRefreshStatus: RefreshStatus.refreshing);
    _refresh(_refreshController);
  }

  @override
  void dispose() {
    _refreshController.dispose();
    super.dispose();
  }

  /// 控制器刷新
  Future<int> _refreshByController() async {
    _rByC = true;
    await _refreshController.requestRefresh();
    _rByC = false;

    return _dataList.length;
  }

  /// 刷新
  Future<int> _refresh(RefreshController controller) async {
    _page = 1;

    final List<T> temp = await widget.onRefresh(widget.pageSize, _rByC);

    _dataList.clear();
    if (temp.isNotEmpty) {
      _dataList.addAll(temp);
    }

    await widget.onListChange?.call(_dataList);

    await Future<void>.delayed(const Duration(milliseconds: 300), () {});

    await widget.onInit?.call(_dataList);

    _refreshController.refreshCompleted();
    _refreshController.loadComplete();

    safeSetState(() {});

    return _dataList.length;
  }

  /// 加载更多
  Future<void> _loadMore(RefreshController controller) async {
    _page++;

    final List<T> _temp = await widget.onLoad!(_page, widget.pageSize);

    if (_temp.isEmpty) {
      ///没有更多了
      _page--;
      _canLoadText = '没有更多了';
      _refreshController.loadNoData();
    } else {
      _dataList.addAll(_temp);

      await widget.onListChange?.call(_dataList);

      if (!mounted) return;
      _refreshController.loadComplete();
    }

    safeSetState(() {});
  }

  /// 移除 `index` 所在 `item`
  void _remove(int index) {
    try {
      safeSetState(() => _dataList.removeAt(index));
    } catch (e) {
      error('移除item出错:$e');
    }
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    if (widget.viewController != null) {
      widget.viewController!._refreshLoadViewState = this;
    }
  }

  @override
  Widget build(BuildContext context) {
    return RefreshView(
      controller: _refreshController,
      onRefresh: _refresh,
      scrollController: widget.scrollController,
      onLoading: widget.onLoad != null ? _loadMore : null,
      scrollDirection: widget.scrollDirection,
      child: _child,
      footerText: _canLoadText,
      // physics: const BouncingScrollPhysics(),
    );
  }

  Widget get _child {
    if (_refreshController.isRefresh) return const LoadingView();
    if (_dataList.isEmpty) return const EmptyView();

    switch (widget.type) {
      case ViewType.list:
        return _buildList;
      case ViewType.grid:
        return _buildGrid;
      case ViewType.waterfall:
        return _buildWaterfall;
      default:
        return _buildList;
    }
  }

  /// 列表视图
  Widget get _buildList => ListView.separated(
        controller: widget.scrollController,
        physics: const BouncingScrollPhysics(),
        itemCount: _dataList.length,
        padding: widget.padding,
        cacheExtent: widget.cacheExtent,
        scrollDirection: widget.scrollDirection,
        itemBuilder: (BuildContext context, int index) {
          return widget.itemBuilder(index, _dataList[index]);
        },
        separatorBuilder: widget.separatorBuilder ?? (_, __) => widget.splitWidget,
      );

  /// 网格视图
  Widget get _buildGrid => GridView.builder(
        cacheExtent: widget.cacheExtent,
        gridDelegate: widget.gridDelegate ?? const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
        controller: widget.scrollController,
        physics: const BouncingScrollPhysics(),
        itemCount: _dataList.length,
        padding: widget.padding,
        scrollDirection: widget.scrollDirection,
        itemBuilder: (BuildContext context, int index) => widget.itemBuilder(index, _dataList[index]),
      );

  /// 瀑布流
  Widget get _buildWaterfall => WaterfallFlow.builder(
        scrollDirection: widget.scrollDirection,
        physics: const BouncingScrollPhysics(),
        cacheExtent: widget.cacheExtent,
        padding: widget.padding,
        itemCount: _dataList.length,
        itemBuilder: (BuildContext context, int index) => widget.itemBuilder(index, _dataList[index]),
        gridDelegate: widget.waterfallDelegate ??
            SliverWaterfallFlowDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,
              crossAxisSpacing: 14,
              mainAxisSpacing: 14,
              lastChildLayoutTypeBuilder: (int i) =>
                  i == _dataList.length ? LastChildLayoutType.foot : LastChildLayoutType.none,
            ),
      );
}

/// 刷新加载视图控制器
class RefreshViewController<T> {
  _RefreshLoadViewState<T>? _refreshLoadViewState;

  Future<int> refresh() async {
    return await _refreshLoadViewState?._refreshByController() ?? 0;
  }

  Future<void> setState() async {
    await _refreshLoadViewState?.safeSetState(() {});
  }

  /// 移除 `index` 所在 `item`
  void remove(int index) {
    try {
      _refreshLoadViewState?._remove(index);
    } catch (e) {
      error('移除item出错:$e');
    }
  }

  void dispose() {
    _refreshLoadViewState = null;
  }
}
